import GameData_blxf from "../GameData/GameData";
import { VendorData_blxf } from "../GameData/VendorData";
import { CsvManager_blxf } from "../Manager/CsvManager";
import { EnumManager_blxf } from "../Manager/EnumManager";
import AudioModule_blxf from "../Module/AudioModule";
import { ConfigModule_blxf } from "../Module/ConfigModule";
import { LoadModule_blxf } from "../Module/LoadModule";
import { NumModule_blxf } from "../Module/NumModule";
import PublicModule_blxf from "../Module/PublicModule";
import { UtilsModule_blxf } from "../Module/UtilsModule";
import DiagueItem_blxf from "./diagueItem";

/**
 * 游戏按钮名字
 */
enum GuestSpineNameType {
    /** 呼吸 */
    NAME_BREATH     = 'breath',
    /** 生气 */
    NAME_ANGRY      = 'angry',
    /** 开心 */
    NAME_HAPPY      = 'happy',
    /** 日常 */
    NAME_NORMAL     = 'idle',
}

const {ccclass, property} = cc._decorator;

/** 游戏客人 */

@ccclass
export default class GuestItem_blxf extends cc.Component {

    @property({ type: cc.Prefab, tooltip: '台词item' })
    dialogueItem: cc.Prefab = null;

    @property({ type: sp.Skeleton, tooltip: '客人动画' })
    guestSkeleton: sp.Skeleton = null;


    @property({ tooltip: '传入参数' })
    _options: any = null;

    @property({ tooltip: '客人台词' })
    _dialogueThis: DiagueItem_blxf = null;

    @property({ tooltip: '出现概率' })
    _loadGuestPercent: string = '70%';
    
    @property({ tooltip: '客人数据' })
    _guestData: any = null;

    @property({ tooltip: '客人台词' })
    _guestDialogueThis: DiagueItem_blxf = null;

    @property({ tooltip: '商品数据' })
    _shopData: any = null;


    _isTouchAudio: boolean = false;

    @property({ tooltip: '是否加载动画中' })
    _isLoadSkeleton: boolean = false;


    _isInitAudio: boolean = false;
    @property({ tooltip: '客人动画id' })
    _spineId: string = null;

    @property({ tooltip: '隐藏菜篮id' })
    _hideTargetId: number = -1;

    // LIFE-CYCLE CALLBACKS:

    onLoad () {}

    start () {
        this._loadGuestPercent = '70%';
    }

    update (dt) {}

    initEvent_blxf () {
        this.node.on('touchstart', this.onTouchGuest_blxf, this);
        this.node['_touchListener'].setSwallowTouches(false);
    }

    initData_blxf ( options: any ) {
        this._options = options;
        this._isInitAudio = false;

        this.loadDialogueItem_blxf();

        this.updateUI_blxf();
    }

    updateUI_blxf () {
        
    }

    /** 获取客人id */
    getGuestId_blxf () {
        let { guestId } = this._options;
        return guestId;
    }

    getGuestDataId_blxf () {
        let { GuestId } = this._guestData || {};
        return Number(GuestId);
    }

    onTouchGuest_blxf () {
        let { guestId, guestTargetId } = this._options;
        let _isAuto = !!guestTargetId;
        if ( _isAuto ) return;

        // 是否有标记摊位
        let _isMark: boolean = VendorData_blxf.instance.onCheckMarkVendorId_blxf();
        if ( _isMark ) return cc.game.emit('onGuestTouchTarget_blxf', guestId);

        let { DIALOGUE_NORMAL, DIALOGUE_START } = EnumManager_blxf.guestDialogueType;
        this.loadGuestDialogue_blxf( !this._isTouchAudio ? DIALOGUE_START : DIALOGUE_NORMAL );

        cc.log('点击客人 >>', guestId);

        if ( !this._isTouchAudio ) {
            this._isTouchAudio = true;
            this.onPlayGuestAudio_blxf();
        }
    }

    loadDialogueItem_blxf () {
        let { checkH } = ConfigModule_blxf.instance;
        let { guestId, guestTargetId } = this._options;

        let _isAuto = !!guestTargetId;
        if ( _isAuto ) return;

        let _xs: number[] = [ 320, -55, -55 ];

        let _x: number = _xs[ guestId - 1 ];
        let _y: number = 182 + 90 + 310 - checkH * 3 / 4 - 20;
        let _nodePos: cc.Vec3 = cc.v3( this.node.x + _x, _y, 0 );
        let _parentNode: cc.Node = cc.find('Canvas/game_panel/vendorPanel');
        let _dialogueNode: cc.Node = LoadModule_blxf.instance.LoadNode_blxf({
            prefabNode: this.dialogueItem, parentNode: _parentNode, position: _nodePos
        })
        if ( !_dialogueNode ) return;

        this._dialogueThis = _dialogueNode.getComponent(DiagueItem_blxf);
        this._dialogueThis.initData_blxf( this._options );
    }

    /** 更新商品数据 */
    updateShopData_blxf ( shopId: number ) {
        this._shopData = VendorData_blxf.instance.findShopData_blxf( shopId );
    }

    /** 播放客人入场音效 */
    onPlayGuestAudio_blxf () {
        if ( !this._guestData ) return;
        
        let { guestTargetId } = this._options;
        let { DialogueAudioId } = this._guestData;
        if ( !DialogueAudioId || guestTargetId ) return;
        if ( PublicModule_blxf.guestAudioTimer > 0 ) return;
        AudioModule_blxf.instance.playAudio_blxf( DialogueAudioId, false, ( a: any, b: any, duration: number )=>{
            this.onRecordAudioData( duration );
        });

        this.loadGuestDialogue_blxf();
    }

    /**
     * 检测是否加载客人
     * @param shopId 目标商品id
     */
    onCheckGuest_blxf ( shopId: number, isNewShopId: boolean = false, isInit: boolean = false ) {
        this.updateShopData_blxf( shopId );

        let _shopNum: number = GameData_blxf.instance.getShopList_blxf().length;
        let _isDefShop: boolean = _shopNum == 2;

        let _cfgGuestList: any[] = VendorData_blxf.instance.getGuestInfo_blxf();
        let _guestData: any = _cfgGuestList.find( guestItem => {
            let { GuestId, isUnlock, LikeShopId } = guestItem;
            if ( Number(GuestId) > 100 ) return;
            let _isHave: boolean = !!PublicModule_blxf.targetGuestIds.find( item => item && item.GuestId == GuestId );
            return isUnlock && LikeShopId == shopId && !_isHave;
        });
        if ( !isInit && !_guestData ) return this.onRandomGuest( _isDefShop );

        let _isAlike: boolean = this._guestData && this._guestData.GuestId == _guestData.GuestId;
        let _isLoad: boolean = isInit || isNewShopId || NumModule_blxf.instance.isChance_blxf( this._loadGuestPercent );
        if ( !_isLoad || !isNewShopId && _isAlike ) return this.onRandomGuest( _isDefShop );

        if ( _guestData ) this._guestData = _guestData;
        // cc.log('this._guestData >非随机客人>', this._guestData);

        this.updateGuestSkeleton_blxf();
    }

    /** 随机客人 */
    onRandomGuest ( _isDefShop: boolean ) {
        // cc.warn('onRandomGuest ', PublicModule_blxf.isGuestAudio)
        let _newShopId: number = VendorData_blxf.instance.getNewShopId_blxf();
        let _unlockGuestList: any[] = GameData_blxf.instance.getGuestList_blxf();
        let _isMoreGuest: boolean = _unlockGuestList.length > 1;

        let { GuestId } = this._guestData || {};
        let { guestPanelThis } = this._options;
        let _guestList: any[] = VendorData_blxf.instance.getGuestInfo_blxf();
        _guestList = _guestList.filter( item => Number(item['GuestId']) < 100 );
        let _newGuestData: any = _guestList.find( guestItem => guestItem.isUnlock && guestItem.LikeShopId == _newShopId );
        let _newGuestId: number = _isMoreGuest && _newGuestData ? _newGuestData.GuestId : null;
        let _loadGuestIds: number[] = guestPanelThis ? guestPanelThis.onGuestIds_blxf() : [];

        _guestList = _guestList.filter( item => {
            if ( _isDefShop ) return item.isUnlock;

            let _isCheck: boolean = _loadGuestIds.includes( Number(item.GuestId) );
            return item.isUnlock && (!_isMoreGuest || item.GuestId != GuestId) && (item.GuestId != _newGuestId) && !_isCheck ;
        });
        _guestList.sort((a, b) => Math.random() - 0.5);

        // cc.log('_guestList >>', _newGuestId, GuestId, _guestList, _loadGuestIds);
        this._guestData = _guestList[0];

        this._guestData && this.updateGuestSkeleton_blxf( true );
    }

    /** 更新客人Spine动画 */
    updateGuestSkeleton_blxf ( isRandom: boolean = false, updateCB: any = null ) {
        let { SpineId, DialogueAudioId } = this._guestData;
        let { guestTargetId } = this._options;
        let _isAuto = !!guestTargetId;

        let _guestId: number = this.getGuestId_blxf();
        if ( !PublicModule_blxf.dialogueGuestId ) {
            PublicModule_blxf.dialogueGuestId = _guestId;
        }
        let _isDialogue: boolean = PublicModule_blxf.dialogueGuestId == _guestId;

        this.updateSkeleton_blxf( SpineId, updateCB, _isDialogue );

        if ( PublicModule_blxf.isGuestAudio && PublicModule_blxf.isGame ) {
            isRandom = false;
            PublicModule_blxf.isGuestAudio = false;
            cc.warn('PublicModule_blxf.isGuestAudio ', PublicModule_blxf.isGuestAudio)
        }

        let _isCheck: boolean = PublicModule_blxf.guestAudioTimer < 0 && !isRandom && !_isAuto && _isDialogue && this._isInitAudio;
        _isCheck && AudioModule_blxf.instance.playAudio_blxf( DialogueAudioId, false, ( a: any, b: any, duration: number )=>{
            this.onRecordAudioData( duration );
        });

        this._dialogueThis && this._dialogueThis.updateGuestData_blxf( this._guestData, this._shopData );

        this._isInitAudio = true;
    }

    /** 记录音效数据 */
    onRecordAudioData ( duration: number ) {
        PublicModule_blxf.guestAudioTimer = duration;
        this.scheduleOnce(()=>{
            PublicModule_blxf.guestAudioTimer = -1;
        }, duration);
    }

    /**
     * 更新动画
     */
    updateSkeleton_blxf ( SpineId: string, updateCB: any, isDialogue: boolean = false ) {
        let _spineData: any = CsvManager_blxf.instance.getSpineDataById_blxf( SpineId );
        if ( !_spineData ) return UtilsModule_blxf.instance.Log_blxf(`查找动画数据失败 SpineId => ${SpineId}`, 2);

        let _isAlike: boolean = this._spineId == SpineId;
        this._spineId = SpineId;

        let { guestId, guestTargetId } = this._options;
        let _isAuto = !!guestTargetId;

        PublicModule_blxf.targetGuestIds[ guestId - 1 ] = this._guestData;

        let _isInit = !this.guestSkeleton;

        let _completeCb = () =>{
            _isInit && this.onPlayGuestAudio_blxf();

            !_isInit && !_isAuto && isDialogue && this.loadGuestDialogue_blxf();

            this.onAnimation_blxf();

            this._isTouchAudio = false;
        }

        if ( !this.guestSkeleton ) {
            // 防止重复加载
            if ( this._isLoadSkeleton ) return;
            this._isLoadSkeleton = true;

            UtilsModule_blxf.instance.createSpine_blxf( SpineId, this.node, ( spineSkeleton: sp.Skeleton )=>{
                this._isLoadSkeleton = false;
                this.guestSkeleton = spineSkeleton;

                this.initEvent_blxf();

                _completeCb();
            });
            return;
        }

        this.onUpdateAnimation_blxf(()=>{
            if ( _isAlike ) return _completeCb();

            let { BundleName, DirName, FileName } = _spineData;
            let _spinePath: string = `${DirName}/${FileName}`;
            LoadModule_blxf.instance.LoadSpine_blxf( BundleName, _spinePath, this.guestSkeleton, ()=>{
                _completeCb();
            })
        }, updateCB, _isAlike);
    }

    /** 客人出现动画 */
    onUpdateAnimation_blxf ( cb: any, updateCB: any, _isAlike: boolean ) {
        let { guestId, guestTargetId } = this._options;
        let _targetId: number = guestId + 1;
        let _isAuto = !!guestTargetId;

        let _node = this.guestSkeleton.node;
        let _opacity = _isAlike ? 255 : 0;
        let _scale: number = _isAlike ? 1 : 0.8;
        cc.tween( _node )
        .to(0.5, { scale: _scale, opacity: _opacity })
        .call(()=>{ 
            cb && cb();
            
            if ( !_isAuto ) {
                this._hideTargetId = _targetId;
                cc.game.emit(`updateImgScale_blxf_${ _targetId }`, false);
            }

            updateCB ? updateCB() : this.onShowAnimation_blxf( _targetId );
        })
        // .to(0.5, { scale: 1, opacity: 255 })
        // .call(()=>{
        //     updateCB && updateCB();
            
        //     cc.game.emit(`updateImgScale_blxf_${ _targetId }`, true);
        // })
        .start();
    }

    onShowAnimation_blxf ( _targetId: number = -1, updateCB: any = null ) {
        if ( !this.guestSkeleton ) return;
        let _node = this.guestSkeleton.node;

        cc.tween( _node )
        .to(0.5, { scale: 1, opacity: 255 })
        .call(()=>{
            updateCB && updateCB();
            
            // 兼容处理
            if ( _targetId == -1 && this._hideTargetId != -1 ) {
                _targetId = this._hideTargetId;
                this._hideTargetId = -1;
            }
            _targetId != -1 && cc.game.emit(`updateImgScale_blxf_${ _targetId }`, true);
        })
        .start();
    }

    /**
     * 播放台词对应动画
     * @param dialogueType 台词类型 
     */
    onAnimation_blxf ( dialogueType: string = '' ) {
        let _animationName: string;
        let { DIALOGUE_OK, DIALOGUE_ANGRY, DIALOGUE_START, DIALOGUE_NORMAL, DIALOGUE_NEW_YEAR } = EnumManager_blxf.guestDialogueType;
        switch ( dialogueType ) {
            case DIALOGUE_OK       : _animationName = GuestSpineNameType.NAME_HAPPY; break;
            case DIALOGUE_ANGRY    : _animationName = GuestSpineNameType.NAME_ANGRY; break;
            case DIALOGUE_START    :
            case DIALOGUE_NORMAL   :
            case DIALOGUE_NEW_YEAR : _animationName = GuestSpineNameType.NAME_NORMAL; break;
            default                : _animationName = GuestSpineNameType.NAME_BREATH; break;
        }
        this.playAnimation_blxf( _animationName );
    }

    /**
     * 播放客人动画
     * @param animationName 动画名
     */
    playAnimation_blxf ( animationName: string ) {
        let isLoop: boolean = animationName == GuestSpineNameType.NAME_BREATH;
        // cc.log('playAnimation_blxf >>', isLoop, animationName);
        UtilsModule_blxf.instance.palyAnimation_blxf( this.guestSkeleton, { animationName, isLoop });

        if ( isLoop ) return;
        let _duration: number = this.getAnimationTime_blxf( animationName );
        this.scheduleOnce(()=>{
            this.playAnimation_blxf( GuestSpineNameType.NAME_BREATH );
        }, _duration)
    }

    /**
     * 获取动画时间
     * @param animationName 动画名
     */
    getAnimationTime_blxf ( animationName: string ) {
        let duration: number = NumModule_blxf.instance.onAnimationTime_blxf( this.guestSkeleton, animationName );
        return duration;
    }



    /**
     * 加载台词
     * @param dailogueType 台词类型 
     */
    loadGuestDialogue_blxf ( dialogueType: string = EnumManager_blxf.guestDialogueType.DIALOGUE_START, isAnimation: boolean = false  ) {
        let { guestPanelThis } = this._options;
        guestPanelThis && guestPanelThis.onHideAllGuestDialogue_blxf();

        let { DIALOGUE_OK } = EnumManager_blxf.guestDialogueType;
        let _isOk: boolean = dialogueType == DIALOGUE_OK;
        !_isOk && this._dialogueThis.loadGuestDialogue_blxf( dialogueType, isAnimation );

        // // if ( !this._isShow ) return;

        // 播放客人动画
        this.onAnimation_blxf( dialogueType );
        
        // if ( isAnimation || !this._guestData ) return;

        // let _dialogueStr: string = this._guestData[ dialogueType ];
        // if ( !_dialogueStr ) {
        //     return UtilsModule_blxf.instance.Log_blxf(`未找到相关台词 talkType => ${dialogueType}`);
        // }

        // let _dialogueList: string[] = _dialogueStr.split('&');
        // _dialogueList.sort((a, b) => Math.random() - 0.5);

        // let _dialogueText: string = _dialogueList[ 0 ];

        // let { ShopName } = this._shopData || { ShopName: '' };
        // _dialogueText = _dialogueText.replace('【目标物品】', ShopName);

        // this.updateDialogueNode_blxf( _dialogueText );
    }

    onHideGuestDialogue_blxf () {
        if ( !this._guestDialogueThis ) return;

        this._guestDialogueThis.onHideDialogue_blxf();
    }
}
